
package com.clf.data.redis.core;

import com.clf.data.redis.core.json.FastJsonRedisTemplate;
import com.google.common.base.Optional;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Description: druid connect test
 *
 * @author <a href="mailto:yrh@qtz360.com">yrh</a>
 * @Date Create on 2018年07月27日
 * @since version1.0 Copyright 2018 QTZ All Rights Reserved.
 */
public interface RedisOperator {

	/**
	 * key/value操作，根据key获得value
	 * 
	 * @param key
	 *            String
	 * @return Optional<String> Optional.absent() means null
	 */
	Optional<String> get(String key);

	/**
	 * key/value操作，根据key获得value，并转换成指定class
	 * 
	 * @param key
	 * @param clz
	 * @return
	 */
	<T> Optional<T> get(String key, Class<T> clz);

	/**
	 * key/value操作，根据key获得value的列表，并转换成指定class
	 * 
	 * @param key
	 *            String
	 * @param clz
	 *            Reference E List<E>
	 * @return Optional<List<E>> Optional.absent() means null
	 */
	<E> Optional<List<E>> getForList(String key, Class<E> clz);

	/**
	 * key/value操作，根据key设置value
	 * 
	 * @param key
	 *            String
	 * @param value
	 *            Object
	 */
	void set(String key, Object value);

	/**
	 * key/value操作，根据key设置value,设置过期时间
	 * 
	 * @param key
	 * @param value
	 * @param second
	 */

	void set(String key, Object value, long second);

	/**
	 * key/value操作，根据key设置value,设置过期时间
	 * 
	 * @param key
	 * @param value
	 * @param timeout
	 * @param unit
	 */
	void set(String key, Object value, long timeout, TimeUnit unit);

	/**
	 *  key/value操作，根据key设置value,只有redis中key不存在时，才插入值
	 *
	 * @param key
	 *            must not be {@literal null}.
	 * @param value
	 *            must not be {@literal null}.
	 * @return
	 * @see <a href="http://redis.io/commands/setnx">Redis Documentation:
	 *      SETNX</a>
	 */
	Optional<Boolean> setNx(String key, Object value);

	/**
	 *  key/value操作，根据key设置value,只有redis中key不存在时，才插入值，并设置过期时间
	 * 
	 * @param key
	 *            String
	 * @param value
	 *            object
	 * @param seconds
	 *            timeout seconds
	 */
	void setEx(String key, Object value, long seconds);

	/**
	 * key/value操作，根据key设置value,只有redis中key不存在时，才插入值，并设置过期时间
	 * 
	 * @param key
	 *            String
	 * @param value
	 *            object
	 * @param timeout
	 *            timeout
	 * @param unit
	 *            time unit
	 */
	void setEx(String key, Object value, long timeout, TimeUnit unit);

	/**
	 * 自增1
	 * 
	 * @param key
	 *            String
	 * @return the incred value
	 */
	Optional<Long> incr(String key);

	/**
	 *自增指定值
	 * 
	 * @param key
	 *            String
	 * @param delta
	 *            increment number
	 * @return eht incred value
	 */
	Optional<Long> incrBy(String key, final long delta);
	/**
	 * 自减指定值
	 * @param key
	 * @param delta
	 * @return
	 */
	Optional<Long> decrBy(String key, final long delta);

	/**
	 * 设置过期时间
	 * @param key
	 *            String
	 * @param seconds
	 *            timeout
	 * @return
	 */
	Optional<Boolean> expire(String key, long seconds);

	/**
	 *设置过期时间
	 * 
	 * @param key
	 *            String
	 * @param timeout
	 *            timeout
	 * @param unit
	 *            time unit
	 * @return
	 */
	Optional<Boolean> expire(String key, long timeout, TimeUnit unit);
	/**
	 * 设置过期时间
	 * @param key
	 * @param date
	 * @return
	 */
	public Optional<Boolean> expireAt(String key, Date date);

	/**
	 * 删除指定的键
	 * 
	 * @param key
	 */
	void del(String key);

	/**
	 * 删除指定的多个键
	 * 
	 * @param keys
	 */
	void del(String... keys);
	/**
	 * 是否存在该键值
	 * @param key
	 * @return
	 */
	Optional<Boolean> hasKey(String key);
	/**
	 * 获得map的值
	 * 
	 * @param key
	 *            Object
	 * @param field
	 *            String
	 * @return the value associated with field, or nil when field is not present
	 *         in the hash or key does not exist.
	 */
	<T> Optional<T> hget(String key, Object field);

	/**
	 * 获得map的值
	 * 
	 * @param key
	 * @param field
	 * @param clz
	 *            the value reference T
	 * @return the value associated with field, or nil when field is not present
	 *         in the hash or key does not exist.
	 */
	<T> Optional<T> hget(String key, Object field, Class<T> clz);

	/**
	 * 获得map的值，list形式
	 * 
	 * @param key
	 * @param field
	 * @param clz
	 * @return
	 */
	<E> Optional<List<E>> hgetForList(String key, Object field, Class<E> clz);

	/**
	 * 设置map的值
	 * 
	 * @param key
	 * @param field
	 * @param value
	 */
	void hset(String key, Object field, String value);

	/**
	 * 设置map的值
	 * 
	 * @param key
	 * @param field
	 * @param value
	 */
	void hset(String key, Object field, Object value);

	/**
	 * 设置map的多个值
	 * @param key
	 * @param hashMap
	 */
	void hmset(String key, Map<Object, Object> hashMap);

	/**
	 *删除map的值
	 * @param key
	 * @param field
	 * @return
	 */
	Optional<Long> hdel(String key, String field);
	/**
	 * 获得RedisTemplate
	 * @return
	 */
	RedisTemplate<String, Object> getTemplate();
	/**
	 * 获得FastJsonRedisTemplate
	 * @return
	 */
	FastJsonRedisTemplate<String, Object> getFastJsonRedisTemplate();

	/**
	 * 忽略redis的异常，如果是，则执行redis下一条命令错误后，将不会抛出异常，但会打印日志 注意，redis命令执行后，会自动失效
	 * 
	 */
	void ignoreRedisException();
}
